#include "argpars.h"

args arguments;

char * const LIFO = "LIFO";
char * const FIFO = "FIFO";

double getNum(char * s) {
	double n = 0, exp = 1;
	unsigned i = 0;
	bool neg=false;

	while ( *s == ' ' ) {
		s++;
	}
	if (*s == '-' || *s == '+') {
		neg = (*s == '-');
		s++;
	}
	if ( *s != '.' && (*s < '0' || *s > '9')) {
		throw PARSEERROR;
	}
	while ( *s <= '9' && *s >= '0' ) {
		char c;
		c = *s;
		i *= 10;
		i += c - '0';
		s++;
	}
	if ( *s == '.' ) {
		s++;
		while ( *s <='9' && *s >= '0' ) {
			n += (*s - '0') * (exp *= 0.1);
			s++;
		}
	}
	return (neg ? -1 : 1) * (i + n);
}

args parse(int argc, char **argv){
	unsigned i = 0, j;
	args res;
	char * p;
	res.part = NA;
	res.file = false;
	res.seed = 1;
	res.report = false;
	res.queueType = 0x0;
	res.termCondition = 0;
	res.capacity = 0;
	res.distribution = _NA;
	res.lam = -1;
	res.mu = -1;
	res.k = -1;
	res.p = -1;
	res.a = -1;
	res.b = -1;
	res.d = -1;
	
	for (i = 1; i < argc; i++) {
		p = *(argv + i);
		if (*p == '-') {
			for ( j = 0; *(p + j) != '\0'; j++) {
				switch ( *(p + j) ) {
				case 'f':
					if (res.file) {
						throw PARSEERROR;
					}
					res.file = true;
					break;
				case 'r':
					if (res.report) {
						throw PARSEERROR;
					}
					res.report = true;
					break;
				case '1':
					if (res.part != NA) {
						throw PARSEERROR;
					}
					res.part = PART1;
					break;
				case '2':
					if (res.part != NA) {
						throw PARSEERROR;
					}
					res.part = PART2;
					break;
				defualt:
					throw PARSEERROR;
				}
			}
		}
		else {
			if ( p[0] == 's' && p[1] == '=' ) {
				res.seed = (unsigned)getNum(p + 2);
			}
			else if ( p[0] == 'l' && p[1] == 'a' && p[2] == 'm' && p[3] == '=' ) {
				res.lam = getNum(p + 4);
			}
			else if ( p[0] == 'm' && p[1] == 'u' && p[2] == '=') {
				res.mu = getNum(p + 3);
			}
			else if ( p[0] == 'B' && p[1] == '=' ) {
				res.capacity = (unsigned) getNum(p + 2);
			}
			else if ( p[0] == 'N' && p[1] == '=' ) {
				res.termCondition =(unsigned)  getNum(p + 2);
			}
			else if ( p[0] == 'd' && p[1] == '=' ) {
				res.d = getNum(p + 2);
			}
			else if ( p[0] == 'a' && p[1] == '=' ) {
				res.a = getNum(p + 2);
			}
			else if ( p[0] == 'b' && p[1] == '=' ) {
				res.b = getNum(p + 2);
			}
			else if ( p[0] == 'k' && p[1] == '=' ) {
				res.k = getNum(p + 2);
			}
			else if ( p[0] == 'p' && p[1] == '=' ) {
				res.p = getNum(p + 2);
			}
			else if ( p[0] == 'L' && p[1] == 'I' && p[2] == 'F' && (p[3] == 'S' || p[3] == 'O')) {
				res.queueType = LIFO;
			}
			else if ( p[0] == 'F' && p[1] == 'I' && p[2] == 'F' && (p[3] == 'S' || p[3] == 'O')) {
				res.queueType = FIFO;
			}
			else if ( p[0] == 'd' && p[1] == 'i' && p[2] == 's' && p[3] == 't' && p[4] == 'r' && p[5] == 'i' && p[6] == '=') {
				char *q;
				q = p + 7;
				if (q[0] == 'U' && q[1] == 'n' && q[2] == 'i' && q[3] == 'f') {
					res.distribution = UNIF;
				}
				else if (q[0] == 'E' && q[1] == 'x' && q[2] == 'p' && q[3] == 'o') {
					res.distribution = EXPO;
				}
				else if (q[0] == 'C' && q[1] == 'o' && q[2] == 'n' && q[3] == 's' && q[4] == 't') {
					res.distribution = CONST;
				}
			}
			else {
				throw PARSEERROR;
			}
		}
	}

	if (res.part == NA || res.termCondition == 0) {
		throw PARSEERROR;
	}
	if (res.part == PART1 && (res.lam < 0 || res.k < 0 || res.p < 0 || res.a < 0)) {
		throw PARSEERROR;
	}
	if (res.part == PART2){
		if(res.distribution == _NA) {
			throw PARSEERROR;
		}
		if(res.distribution == CONST && res.d < 0) {
			throw PARSEERROR;
		}
		if(res.distribution == UNIF && (res.a < 0 || res.b < 0 || res.a > res.b)) {
			throw PARSEERROR;
		}
		if(res.distribution == EXPO && res.mu < 0) {
			throw PARSEERROR;
		}
	}
	if (res.queueType == 0x0) {
		res.queueType = FIFO;
	}
	return res;
}

